<template>
  <div>
    <div class="editor">
      <!-- 工具栏 -->
      <Toolbar
        class="editor-tool"
        :mode="mode"
        :editor="editor"
        :default-config="toolbarConfig"
      />
      <!-- 编辑器 -->
      <Editor
        v-model="html"
        class="editor-edit"
        :style="{ 'height': height }"
        :mode="mode"
        :default-config="editorConfig"
        @onCreated="onCreated"
      />
    </div>
  </div>
</template>

<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { DomEditor } from '@wangeditor/editor'
import '@wangeditor/editor/dist/css/style.css'
import { getToken, getSubject } from '@/utils/storage'
import Configs from '@/utils/request/config'
import appConfig from '@/config'
const { appKey, appSecret, clientId } = appConfig
import MD5 from 'md5'
const getParamStr = params => {
  return Object.keys(params)
    .sort((n, m) => {
      var a = n.toLowerCase()
      var b = m.toLowerCase()
      if (a < b) return -1
      if (a > b) return 1
      return 0
    })
    .map(key => `${key}=${params[key]}`)
    .join('&')
}

export default {
  name: 'RichText',
  components: { Editor, Toolbar },
  props: {
    value: String,
    bizId: {
      type: [String, Number],
      default: 150
    },
    mode: {
      type: String,
      default: 'default'
    },
    height: {
      type: String,
      default: '300px'
    },
    excludeKeys: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    const baseUrl = Configs.getBaseURL('base', false)
    const that = this
    const timestamp = +new Date()
    const query = {
      timestamp,
      appid: appKey
    }
    const sign = MD5(`${getParamStr(query)}&key=${appSecret}`)
    const serverUrl = `${baseUrl}/admin/file/upload?appid=${appKey}&timestamp=${timestamp}&sign=${sign}`
    const headers = {
      'client-id': clientId
    }
    const token = getToken()
    const subject = getSubject()
    if (subject) {
      headers['subject'] = subject
    }
    if (token) {
      headers['token'] = token
    }
    return {
      html: '',
      editor: null,
      toolbarConfig: {
        // toolbarKeys: [ /* 显示哪些菜单，如何排序、分组 */ ],
        excludeKeys: this.excludeKeys
      },
      editorConfig: {
        placeholder: '请输入内容...',
        autoFocus: false,
        // 所有的菜单配置，都要在 MENU_CONF 属性下
        MENU_CONF: {
          // color: {
          //   colors: ['#000', '#333', '#666']
          // },
          uploadImage: {
            server: serverUrl,
            fieldName: 'file',
            // 单个文件的最大体积限制，默认为 2M
            maxFileSize: 10 * 1024 * 1024, // 1M
            allowedFileTypes: ['image/*'],
            headers,
            customInsert(res, insertFn) {
              // 图片上传并返回结果，自定义插入图片的事件（而不是编辑器自动插入图片！！！）
              // insertImg 是插入图片的函数，editor 是编辑器对象，result 是服务器端返回的结果

              // 举例：假如上传图片成功后，服务器端返回的是 {url:'....'} 这种格式，即可这样插入图片：
              if (res.success) {
                var url = res.data
                insertFn(url)
              } else {
                that.$message.error(res.errMessage || '未知错误')
              }

              // result 必须是一个 JSON 格式字符串！！！否则报错
            }
          },
          uploadVideo: {
            server: serverUrl,
            fieldName: 'file',
            // 单个文件的最大体积限制，默认为 2M
            maxFileSize: 1024 * 1024 * 1024, // 1M
            allowedFileTypes: ['video/*'],
            timeout: 60 * 60 * 1000,
            headers,
            customInsert(res, insertFn) {
              // 图片上传并返回结果，自定义插入图片的事件（而不是编辑器自动插入图片！！！）
              // insertImg 是插入图片的函数，editor 是编辑器对象，result 是服务器端返回的结果

              // 举例：假如上传图片成功后，服务器端返回的是 {url:'....'} 这种格式，即可这样插入图片：
              if (res.success) {
                var url = res.data
                insertFn(url)
              } else {
                that.$message.error(res.errMessage || '未知错误')
              }

              // result 必须是一个 JSON 格式字符串！！！否则报错
            },
            onFailed(file, res) {
              console.log(`${file.name} 上传失败`, res)
            },
            // 上传错误，或者触发 timeout 超时
            onError(file, err, res) {
              console.log(`${file.name} 上传出错`, err, res)
            }
          }
        }
      }
    }
  },
  watch: {
    value(val) {
      this.html = val
    }
  },
  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // 组件销毁时，及时销毁 editor ，重要！！！
  },
  mounted() {
    console.log('mounted', this.html)
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor) // 【注意】一定要用 Object.seal() 否则会报错
      setTimeout(() => {
        console.log('Toolbar默认配置', DomEditor.getToolbar(this.editor))
        console.log('编辑器默认配置', this.editor.getConfig())
      }, 3000)
    },
    submit() {
      this.$emit('input', this.editor.getHtml())
    },
    onChange(editor) {
      // console.log('onChange', editor, editor.getFragment(), editor.getHtml()) // onChange 时获取编辑器最新内容
    }
  }
}
</script>
<style lang="scss" scoped>
.editor{
  border: 1px solid #ccc;
  margin-top: 10px;
  .editor-tool {
    border-bottom: 1px solid #ccc
  }
  .editor-edit {
    overflow: hidden;
  }
}
</style>
